<?php
/**
 * 系统配置管理控制器
 * 提供系统配置的增删改查和管理功能
 */

namespace app\controller;

use app\BaseController;
use app\service\SystemConfigService;
use think\Request;
use think\Response;
use think\facade\Validate;

class SystemConfigController extends BaseController
{
    protected $configService;

    public function __construct()
    {
        $this->configService = new SystemConfigService();
    }

    /**
     * 获取配置列表
     * @param Request $request
     * @return Response
     */
    public function index(Request $request): Response
    {
        try {
            $group = $request->param('group', '');
            $configs = $this->configService->getAllConfigs($group);
            
            return $this->success([
                'configs' => $configs,
                'groups' => $this->configService->getConfigGroups(),
                'types' => $this->configService->getConfigTypes()
            ], '获取配置成功');
            
        } catch (\Exception $e) {
            return $this->error('获取配置失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取单个配置
     * @param Request $request
     * @return Response
     */
    public function read(Request $request): Response
    {
        try {
            $key = $request->param('key');
            if (empty($key)) {
                return $this->error('配置键不能为空');
            }
            
            $value = $this->configService->get($key);
            
            return $this->success([
                'key' => $key,
                'value' => $value
            ], '获取配置成功');
            
        } catch (\Exception $e) {
            return $this->error('获取配置失败: ' . $e->getMessage());
        }
    }

    /**
     * 创建配置
     * @param Request $request
     * @return Response
     */
    public function save(Request $request): Response
    {
        try {
            $data = $request->only([
                'key', 'value', 'desc', 'type', 'group', 'options'
            ]);
            
            // 验证必填字段
            $validate = Validate::rule([
                'key' => 'require|alphaNum',
                'value' => 'require',
                'desc' => 'require',
                'type' => 'require|in:text,number,bool,json,select,multiselect,textarea,password,url,email,file,image',
                'group' => 'require'
            ]);
            
            if (!$validate->check($data)) {
                return $this->error('参数验证失败: ' . $validate->getError());
            }
            
            // 验证配置值
            $validation = $this->configService->validateConfig(
                $data['key'], 
                $data['value'], 
                $data['type']
            );
            
            if (!$validation['valid']) {
                return $this->error('配置值验证失败: ' . implode(', ', $validation['errors']));
            }
            
            $options = [];
            if (!empty($data['options'])) {
                if (is_string($data['options'])) {
                    $options = json_decode($data['options'], true) ?: [];
                } else {
                    $options = $data['options'];
                }
            }
            
            $result = $this->configService->set(
                $data['key'],
                $data['value'],
                $data['desc'],
                $data['type'],
                $data['group'],
                $options
            );
            
            if ($result) {
                return $this->success([], '配置创建成功');
            } else {
                return $this->error('配置创建失败');
            }
            
        } catch (\Exception $e) {
            return $this->error('配置创建失败: ' . $e->getMessage());
        }
    }

    /**
     * 更新配置
     * @param Request $request
     * @return Response
     */
    public function update(Request $request): Response
    {
        try {
            $key = $request->param('key');
            if (empty($key)) {
                return $this->error('配置键不能为空');
            }
            
            $data = $request->only([
                'value', 'desc', 'type', 'group', 'options'
            ]);
            
            // 验证配置值
            if (isset($data['value']) && isset($data['type'])) {
                $validation = $this->configService->validateConfig(
                    $key, 
                    $data['value'], 
                    $data['type']
                );
                
                if (!$validation['valid']) {
                    return $this->error('配置值验证失败: ' . implode(', ', $validation['errors']));
                }
            }
            
            $options = [];
            if (!empty($data['options'])) {
                if (is_string($data['options'])) {
                    $options = json_decode($data['options'], true) ?: [];
                } else {
                    $options = $data['options'];
                }
            }
            
            $result = $this->configService->set(
                $key,
                $data['value'] ?? $this->configService->get($key),
                $data['desc'] ?? '',
                $data['type'] ?? 'text',
                $data['group'] ?? 'basic',
                $options
            );
            
            if ($result) {
                return $this->success([], '配置更新成功');
            } else {
                return $this->error('配置更新失败');
            }
            
        } catch (\Exception $e) {
            return $this->error('配置更新失败: ' . $e->getMessage());
        }
    }

    /**
     * 批量更新配置
     * @param Request $request
     * @return Response
     */
    public function batchUpdate(Request $request): Response
    {
        try {
            $configs = $request->param('configs', []);
            if (empty($configs) || !is_array($configs)) {
                return $this->error('配置数据不能为空');
            }
            
            // 验证每个配置项
            foreach ($configs as $key => $data) {
                if (isset($data['value']) && isset($data['type'])) {
                    $validation = $this->configService->validateConfig(
                        $key, 
                        $data['value'], 
                        $data['type']
                    );
                    
                    if (!$validation['valid']) {
                        return $this->error("配置 {$key} 验证失败: " . implode(', ', $validation['errors']));
                    }
                }
            }
            
            $result = $this->configService->setBatch($configs);
            
            if ($result) {
                return $this->success([], '批量更新配置成功');
            } else {
                return $this->error('批量更新配置失败');
            }
            
        } catch (\Exception $e) {
            return $this->error('批量更新配置失败: ' . $e->getMessage());
        }
    }

    /**
     * 删除配置
     * @param Request $request
     * @return Response
     */
    public function delete(Request $request): Response
    {
        try {
            $key = $request->param('key');
            if (empty($key)) {
                return $this->error('配置键不能为空');
            }
            
            $result = $this->configService->delete($key);
            
            if ($result) {
                return $this->success([], '配置删除成功');
            } else {
                return $this->error('配置删除失败');
            }
            
        } catch (\Exception $e) {
            return $this->error('配置删除失败: ' . $e->getMessage());
        }
    }

    /**
     * 初始化默认配置
     * @param Request $request
     * @return Response
     */
    public function initDefault(Request $request): Response
    {
        try {
            $result = $this->configService->initDefaultConfigs();
            
            if ($result) {
                return $this->success([], '初始化默认配置成功');
            } else {
                return $this->error('初始化默认配置失败');
            }
            
        } catch (\Exception $e) {
            return $this->error('初始化默认配置失败: ' . $e->getMessage());
        }
    }

    /**
     * 导出配置
     * @param Request $request
     * @return Response
     */
    public function export(Request $request): Response
    {
        try {
            $group = $request->param('group', '');
            $configs = $this->configService->exportConfigs($group);
            
            $filename = 'system_configs_' . ($group ?: 'all') . '_' . date('YmdHis') . '.json';
            
            return response(json_encode($configs, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT))
                ->header([
                    'Content-Type' => 'application/json',
                    'Content-Disposition' => 'attachment; filename=' . $filename
                ]);
                
        } catch (\Exception $e) {
            return $this->error('导出配置失败: ' . $e->getMessage());
        }
    }

    /**
     * 导入配置
     * @param Request $request
     * @return Response
     */
    public function import(Request $request): Response
    {
        try {
            $file = $request->file('file');
            if (!$file) {
                return $this->error('请选择要导入的文件');
            }
            
            $content = file_get_contents($file->getPathname());
            $configs = json_decode($content, true);
            
            if (!$configs || !is_array($configs)) {
                return $this->error('文件格式错误，必须是有效的JSON格式');
            }
            
            $result = $this->configService->importConfigs($configs);
            
            if ($result) {
                return $this->success([], '导入配置成功');
            } else {
                return $this->error('导入配置失败');
            }
            
        } catch (\Exception $e) {
            return $this->error('导入配置失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取配置分组
     * @param Request $request
     * @return Response
     */
    public function groups(Request $request): Response
    {
        try {
            $groups = $this->configService->getConfigGroups();
            
            return $this->success([
                'groups' => $groups
            ], '获取配置分组成功');
            
        } catch (\Exception $e) {
            return $this->error('获取配置分组失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取配置类型
     * @param Request $request
     * @return Response
     */
    public function types(Request $request): Response
    {
        try {
            $types = $this->configService->getConfigTypes();
            
            return $this->success([
                'types' => $types
            ], '获取配置类型成功');
            
        } catch (\Exception $e) {
            return $this->error('获取配置类型失败: ' . $e->getMessage());
        }
    }

    /**
     * 验证配置值
     * @param Request $request
     * @return Response
     */
    public function validateConfig(Request $request): Response
    {
        try {
            $key = $request->param('key', '');
            $value = $request->param('value');
            $type = $request->param('type', 'text');
            
            $validation = $this->configService->validateConfig($key, $value, $type);
            
            return $this->success([
                'valid' => $validation['valid'],
                'errors' => $validation['errors']
            ], '验证完成');
            
        } catch (\Exception $e) {
            return $this->error('验证失败: ' . $e->getMessage());
        }
    }

    /**
     * 清除配置缓存
     * @param Request $request
     * @return Response
     */
    public function clearCache(Request $request): Response
    {
        try {
            // 这里可以调用缓存清理方法
            cache(null); // 清除所有缓存（简化实现）
            
            return $this->success([], '清除缓存成功');
            
        } catch (\Exception $e) {
            return $this->error('清除缓存失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取系统信息
     * @param Request $request
     * @return Response
     */
    public function systemInfo(Request $request): Response
    {
        try {
            $info = [
                'php_version' => PHP_VERSION,
                'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown',
                'system' => php_uname(),
                'memory_limit' => ini_get('memory_limit'),
                'max_execution_time' => ini_get('max_execution_time'),
                'upload_max_filesize' => ini_get('upload_max_filesize'),
                'post_max_size' => ini_get('post_max_size'),
                'mysql_version' => $this->getMysqlVersion(),
                'disk_free_space' => $this->formatBytes(disk_free_space('.')),
                'disk_total_space' => $this->formatBytes(disk_total_space('.')),
                'extensions' => $this->getRequiredExtensions()
            ];
            
            return $this->success([
                'system_info' => $info
            ], '获取系统信息成功');
            
        } catch (\Exception $e) {
            return $this->error('获取系统信息失败: ' . $e->getMessage());
        }
    }

    /**
     * 获取MySQL版本
     * @return string
     */
    private function getMysqlVersion(): string
    {
        try {
            $version = \think\facade\Db::query('SELECT VERSION() as version');
            return $version[0]['version'] ?? 'Unknown';
        } catch (\Exception $e) {
            return 'Unknown';
        }
    }

    /**
     * 格式化字节数
     * @param int $bytes
     * @return string
     */
    private function formatBytes(int $bytes): string
    {
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $bytes /= (1 << (10 * $pow));
        
        return round($bytes, 2) . ' ' . $units[$pow];
    }

    /**
     * 获取必需的PHP扩展
     * @return array
     */
    private function getRequiredExtensions(): array
    {
        $required = [
            'pdo', 'pdo_mysql', 'curl', 'json', 'mbstring', 
            'openssl', 'fileinfo', 'gd', 'zip'
        ];
        
        $result = [];
        foreach ($required as $ext) {
            $result[$ext] = extension_loaded($ext);
        }
        
        return $result;
    }
}